import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter_common_utils/common_utils_export.dart';
import 'package:path_provider/path_provider.dart';
import 'http_manager.dart';
import 'package:path/path.dart' as path;

class DownloadManager {
  static const TAG = "DownloadManager";

  /// 安全下载（带临时文件处理）
  static Future<File> download({
    required String url,
    String? fileName,
    bool enableResume = false, // 是否启用断点续传
    bool forceDownload = false, //是否强制重新下载（覆盖已存在文件）
    void Function(int progress)? onProgress, // 进度回调（百分比）
    void Function(File file)? onSuccess, // 成功回调
    void Function(dynamic error)? onError, // 错误回调
  }) async {
    fileName = fileName ?? getFileNameFromUrl(url);
    //C:\Users\likun\AppData\Local\com.vinka.service\Vinka Service
    final dir = await getApplicationCacheDirectory();

    //缓存文件
    final tempFile = File('${dir.path}/$fileName.temp');
    //最终文件
    final finalFile = File('${dir.path}/$fileName');

    // 检查文件是否存在且不需要强制下载
    if (await finalFile.exists() && !forceDownload) {
      LogUtils.e('$TAG ✅ 文件已存在，直接返回缓存');
      return finalFile;
    }

    // 清理可能存在的旧临时文件
    if (forceDownload && await tempFile.exists()) {
      await tempFile.delete();
    }
    if (forceDownload && await finalFile.exists()) {
      await finalFile.delete();
    }
    // 清理可能存在的旧临时文件（除非启用断点续传）
    if (!enableResume && await tempFile.exists()) {
      await tempFile.delete();
    }

    // 创建临时文件（如果不存在）
    if (!await tempFile.exists()) {
      await tempFile.create();
    }

    // 获取已下载长度（用于断点续传）
    final startByte = enableResume ? await tempFile.length() : 0;
    LogUtils.e('$TAG 开始下载: $url');
    try {
      await HttpManager.dio.download(
        url,
        tempFile.path,
        options: Options(
          headers: {'range': 'bytes=$startByte-'}, // 断点续传头
        ),
        onReceiveProgress: (received, total) {
          // 精确计算总进度（兼容续传）
          final percent = (received + startByte) / (total + startByte) * 100;
          final rounded = percent.clamp(0, 100).toInt();
          LogUtils.e('$TAG ⏳ 进度: ${rounded.toStringAsFixed(1)}%');
          onProgress?.call(rounded); // 实时进度（包含小数）
        },
        deleteOnError: false, // 手动处理错误
      );
      // 下载完成后重命名文件
      await tempFile.rename(finalFile.path);
      LogUtils.e('$TAG 🎉 文件下载完成: ${finalFile.path}');
      onProgress?.call(100);
      onSuccess?.call(finalFile);
      return finalFile;
    } catch (e) {
      LogUtils.e('$TAG ❌ 下载异常: ${e.toString()}');
      // 清理临时文件（除非启用断点续传）
      if (!enableResume) await tempFile.delete();
      // 触发错误回调
      onError?.call(e);
      rethrow;
    }
  }

  /// 启动时清理残留临时文件
  static Future<void> cleanTempFiles() async {
    final dir = await getApplicationDocumentsDirectory();
    final files = dir.list().where((f) => f.path.endsWith('.temp'));

    await for (var file in files) {
      if (file is File) {
        await file.delete();
        print('已清理临时文件: ${file.path}');
      }
    }
  }

  /// 从 URL 中提取安全文件名
  static String getFileNameFromUrl(String url) {
    final uri = Uri.parse(url);

    // 获取路径并处理特殊字符
    String filePath = uri.path;
    String fileName = path.basename(filePath); // 自动处理路径中的斜杠

    // 处理空文件名（如URL以/结尾）
    if (fileName.isEmpty || fileName == '.') {
      fileName = uri.host + path.extension(filePath); // 使用域名+扩展名
    }

    // URL 解码（处理%20等编码）
    fileName = Uri.decodeComponent(fileName);

    // 替换非法字符（跨平台安全）
    fileName = fileName.replaceAll(RegExp(r'[<>:"/\\|?*]'), '_');

    // 处理无扩展名情况
    if (path.extension(fileName).isEmpty) {
      fileName += '_${DateTime.now().millisecondsSinceEpoch}';
    }

    return fileName;
  }
}
